package cn.wolfcode.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * SpringBoot 配置类，我们可以自己创建对象后交给 Spring 容器去管理
 */
@Configuration  // 表示是 Spring 配置类
public class ChatConfiguration {
    // 我们需要创建一个 Bean(对象) 。因为向量存储的对象并不会被 SpringBoot 自动装配。
    // 他并不是默认在 SpringBoot 容器中的，所以需要我们自行配置。
    // 将来我们是需要将文件 切分 嵌入到 向量数据库中。
    // 所以 嵌入的模型会被 SpringBoot 自动装配

        @Bean   // 下面方法的返回值会被 Spring 容器所管理。
        public VectorStore vectorStore(EmbeddingModel embeddingModel){
            // SimpleVectorStore：是基于内存的轻量级存储组件。特别适合处理嵌入模型转换后的数据。
            // SimpleVectorStore.builder(embeddingModel).build(); 将模型使用 embeddingModel（嵌入技术） 放入到
            // 向量数据库中，.build() 构建一个内存向量存储数据库。
            VectorStore vectorStore = SimpleVectorStore.builder(embeddingModel).build();
            return vectorStore;
        }

        @Bean
        public ChatMemory chatMemor(){
            return new InMemoryChatMemory();
        }
    @Bean
    public ChatClient client(ChatModel chatModel,VectorStore vectorStore,ChatMemory chatMemory) {
        // 构建 ChatClient 客户端聊天模型
        ChatClient client = ChatClient.builder(chatModel)
                // 设置系统默认输出语句。
                .defaultSystem("你是叩丁狼的一个客服，你的名字叫做狼狼，你需要根据用户提供的问题来给出合适的回答")
                // 默认通知，通知其客户端应该具有的功能是什么
                .defaultAdvisors(
                        // QuestionAnswerAdvisor 基于向量存储的问题进行检索回答的一个顾问。RAG增强。
                        // 参数 vectorStore: 向量存储的实例，我们在上面配置过了。用户相似搜索。
                        // SearchRequest：搜索请求的构建器.topK(4) 返回相似的4条。
                        // similarityThresholdAll 不设置阈值，返回所有相似的结果。
                        // 工作流程：
                        // 用户提问时，会先去 vectorStore 向量数据中检索相关内容。
                        // 使用余弦相似度等算法计算查询先来个i昂数据库中相匹配的数据。
                        // 返回 topK 相关的数字。 4 条相似的结果做为上下文 AI 的增强。
                        // 返回所有相似结果
                        new QuestionAnswerAdvisor(vectorStore,
                                SearchRequest.builder().topK(4).similarityThresholdAll().build()),
                        // 内存记忆
                        // PromptChatMemoryAdvisor ： 记忆提示的顾问。
                        // PromptChatMemoryAdvisor 是 Spring AI 框架中用来管理对话上下文的组件。
                        // 通过历史会话，增强 AI模型的上下文感知能力。
                        // 从而获得记忆功能。
                        new PromptChatMemoryAdvisor(chatMemory),
                        // 日志框架。记录 AI 交互提供日志。
                        new SimpleLoggerAdvisor()
                ).build();
        return client;
    }
}
